﻿using HBase;
using System;
using System.Linq;
using System.Net.Sockets;

namespace hconnect
{

    public abstract class SocketZtTaskConnect :ZtTaskConnect {
        protected Socket socket = null;
        public bool sendTask(object task ,int begin) {
            fileAll(InfoCode.fileAll_send_task, "发送任务{0}", JsonUtil.mySerializeObject(task));
            if (StatusCache.test) {
                return true;
            }
        
            return send(task ,begin);
        }
        protected virtual bool send(Object task ,int begin) {
           
                throw new Exception(this.className + "的 send方法未实现");
        }
        protected bool Send(byte[] packet) {//发报文

            if(   noConn()) {
                return false;
            }
            try {
                int size = socket.Send(packet);
                bool send = size == packet.Length;
                if( !send ) {
                    forceDisConnection();
                }
                return send;
            } catch  {
                forceDisConnection();
                throw ;
            }
        }
        public byte[] ReadTelex(int bufferSize) {//接收报文
            if (noConn()) {
                return null;
            }
            byte[] array = new byte[bufferSize];
            try {

                int count = socket.Receive(array);
                return array.Take(count).ToArray<byte>();
            } catch  {
                forceDisConnection();
                throw ;
            }
        }
        protected virtual void forceDisConnection() {
            if( socket == null ) {
                return;
            }
            try {
                socket.Close();
                socket.Dispose();
                fileAll(InfoCode.fileAll_tcp_dispose,"异常断开连接" + ip + ":" + port);
            } catch {
                throw new Exception("关闭连接异常" + className + ip + ":" + port);
            }

            socket = null;
        }

        public virtual bool afterConnect() {
            return true;
        }
        protected override bool reConnect() {
            if( StatusCache.test ) {
                return true;
            }
            lock( className ) {
                if( !noConn() ) {
                    return true;
                }
                forceDisConnection();
                socket = new Socket(AddressFamily.InterNetwork ,SocketType.Stream ,ProtocolType.Tcp);
                socket.ReceiveTimeout = 4000;
                socket.SendTimeout = 4000;
            
                try {
                    socket.Connect(ipEndPoint);
                } catch( Exception e ) {
                    fileAll(InfoCode.fileAll_tcp_conecting_exception, ip + e.Message);
                    return false;
                }



                afterConnect();
                if( noConn() ) {
                    forceDisConnection();
                }
                console(InfoCode.consle_Connetion_success, ip + ":" + port + "成功连接");
            }

            return true;
        }
        protected bool noConn() {
            if( StatusCache.test ) {
                return true;
            }
            if( socket == null ) {
                return true;
            }
            return !socket.Connected;
        }
    }
}
